/*
    Bandleader
    Copyright (c) 2006 by Grant Yoshida

    Licensed under the GPL version 2 or later,
    please see COPYING for details.
*/

#include "Document.h"
//
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>

Document::Document() :
    m_chords(),
    m_timeSignature(4, 4)
{
    // dummy data

    //
    m_chords.push_back("C");
    m_chords.push_back("");
    m_chords.push_back("F");
    m_chords.push_back("");
    //
    m_chords.push_back("G");
    m_chords.push_back("");
    m_chords.push_back("F");
    m_chords.push_back("");
    //
    m_chords.push_back("C");
    m_chords.push_back("");
    m_chords.push_back("F");
    m_chords.push_back("");
    //
    m_chords.push_back("G");
    m_chords.push_back("");
    m_chords.push_back("F");
    m_chords.push_back("");
}

QString Document::fileName() const
{
    return m_fileName;
}

const TimeSignature &Document::timeSignature() const
{
    return m_timeSignature;
}

//
// Chords
//

QStringList Document::chords() const
{
    return m_chords;
}

QString Document::chordAt(int index) const
{
    QString chord;

    if (validChordIndex(index)) {
       chord = m_chords[index];
    }

    return chord;
}

void Document::setChord(int index, const QString &chord)
{
    if (validChordIndex(index)) {
        m_chords[index] = chord;
    }
}

void Document::clearChord(int index)
{
    setChord(index, "");
}

int Document::numChords() const
{
    return m_chords.size();
}

void Document::insertChord(int index, const QString &chord)
{
    m_chords.insert(index, chord);
}

void Document::insertEmptyBar(int index)
{
    int barNumber = barNumberOf(index);

    int indexToInsertAt = indexOf(barNumber);

    for (int i = 0; i < m_timeSignature.beatsPerMeasure(); ++i) {
        insertChord(i + indexToInsertAt, "");
    }
}

void Document::insertEmptyBarAfter(int index)
{
    int barNumber = barNumberOf(index);

    int nextBarIndex = indexOf(barNumber+1);

    insertEmptyBar(nextBarIndex);
}

void Document::deleteChord(int index)
{
    if (validChordIndex(index)) {
        m_chords.removeAt(index);
    }
}

void Document::deleteBar(int index)
{
    int barNumber = barNumberOf(index);

    int firstIndexInBar = indexOf(barNumber);

    for (int i = 0; i < m_timeSignature.beatsPerMeasure(); ++i) {
        deleteChord(firstIndexInBar);
    }
}

void Document::insertChords(int index, const QStringList &chordsToInsert)
{
    QStringList chords(chordsToInsert);

    while (!chords.empty()) {
        m_chords.insert(index, chords.takeLast());
    }
}

QStringList Document::chordsInBar(int barNumber) const
{
    int index = indexOf(barNumber);

    return m_chords.mid(index, m_timeSignature.beatsPerMeasure());
}

int Document::barNumberOf(int index) const
{
    return index / m_timeSignature.beatsPerMeasure();
}

int Document::indexOf(int barNumber) const
{
    return barNumber * m_timeSignature.beatsPerMeasure();
}

//
// I/O
//

void Document::saveAsMma(QTextStream &stream)
{
    stream << "// Autogenerated by Bandleader\n\n";

    QString groove("Swing");
    stream << "Groove " << groove << "\n\n";

    bool metronome = false;
    if (metronome)
        stream << "z * 2\n\n";

    int beat = 1;
    int barNumber = 1;
    const int beatsPerMeasure = m_timeSignature.beatsPerMeasure();

    foreach (QString chord, m_chords) {
        if (chord.isEmpty())
            chord = "/";

        if (beat == 1) {
            stream << barNumber
                   << " "
                   << chord;

            ++beat;
        }
        else if (beat == beatsPerMeasure) {
            stream << " " << chord << "\n";

            beat = 1;
            ++barNumber;
        }
        else {
            stream << " " << chord;
            ++beat;
        }
    }
}

void Document::saveAsBandleader(QTextStream &stream)
{
    // TODO
}

void Document::saveAs(QFile &file)
{
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream stream(&file);

        QString fileName(file.fileName());

        if (fileName.endsWith(".mma"))
            saveAsMma(stream);
        else if (fileName.endsWith(".bandleader"))
            saveAsBandleader(stream);
    }
}

void Document::saveAs(const QString &fileName)
{
    QFile file(fileName);
    saveAs(file);

    m_fileName = fileName;

    QString name(QFileInfo(fileName).baseName());
    nameChanged(name);
}

bool Document::validChordIndex(int index) const
{
    return index >= 0 && index < m_chords.size();
}
